﻿///***************************************************************
/// 시  스  템 : SMFramework
/// 단위시스템 : Utility
/// 계      층 : Framework Utility
/// 프로그램명 : ConversionUtil
/// 파  일  명 : ConversionUtil.cs
/// 설      명 : 데이터 변환/치환관련 유틸리티
///***************************************************************
/// 수정ID 일자       이름     내용
///---------------------------------------------------------------
/// CH001  2008-07-02 송시명   최초 작성
///***************************************************************
///
using System;
using System.Data.SqlClient;

using SMFramework.Data;
using System.Data;

namespace SMFramework.Utility
{
	/// <summary>
	/// 데이터 변환/치환관련 유틸리티
	/// </summary>
	public sealed class ConversionUtil
	{
        private ConversionUtil()
		{
		}

		#region 특수문자를 아스키문자로 치환

		/// <summary>
		/// 특수문자를 아스키문자로 치환
		/// </summary>
		/// <param name="ps_data">치환할 문자열</param>
		/// <returns>string</returns>
		public static string SpecStr2Asc(string ps_data)
		{
			string ls_return = "";
			for (int i = 0; i < ps_data.Length; i++)
			{
				string ls_temp = ps_data.Substring(i, 1);
				string ls_temp_all = "";
				switch (ls_temp)
				{
					case "<":
						ls_temp_all = ls_temp.Replace("<", "&lt;");
						break;
					case ">":
						ls_temp_all = ls_temp.Replace(">", "&gt;");
						break;
					case "%":
						ls_temp_all = ls_temp.Replace("%", "&#37;");
						break;
					case "'":
						ls_temp_all = ls_temp.Replace("'", "&#39;");
						break;
					case "(":
						ls_temp_all = ls_temp.Replace("(", "&#40;");
						break;
					case ")":
						ls_temp_all = ls_temp.Replace(")", "&#41;");
						break;
					default:
						ls_temp_all = ls_temp;
						break;
				}
				ls_return += ls_temp_all;
			}
			return ls_return;
		}
		
		#endregion

		#region 아스키문자를 특수문자로 치환

		/// <summary>
		/// 아스키문자를 특수문자로 치환
		/// </summary>
		/// <param name="ps_data">치환할 문자열</param>
		/// <returns>string</returns>
		public static string Asc2SpecStr(string ps_data)
		{
			string ls_return = "";
			ps_data = ps_data.Replace("&lt;", "<");
			ps_data = ps_data.Replace("&gt;", ">");
			ps_data = ps_data.Replace("&#37;", "%");
			ps_data = ps_data.Replace("&#39;", "'");
			ps_data = ps_data.Replace("&#40;", "(");
			ps_data = ps_data.Replace("&#41;", ")");
			ls_return = ps_data;

			return ls_return;
		}
		
		#endregion
		
		#region 기본값 지정

		/// <summary>
		/// 데이터가 없으면 지정된 문자로 치환 / 지정된 문자를 지정하지 않으면 빈값으로
		/// </summary>
		/// <param name="ps_data">저장할 값</param>
		/// <param name="ps_default">지정된 문자</param>
		/// <returns>string</returns>
		public static string DefaultValue(string ps_data, string ps_default)
		{
			if (String.IsNullOrEmpty(ps_data))
			{
				if (String.IsNullOrEmpty(ps_default))
				{
					return "";
				}
				else
				{
					return ps_default;
				}
			}
			else
			{
				return ps_data;
			}
		}

		/// <summary>
		///  데이터가 없으면 빈값 리턴
		/// </summary>
		/// <param name="ps_data">저장할 값</param>
		/// <returns>string</returns>
		public static string DefaultValue(string ps_data)
		{
			if (String.IsNullOrEmpty(ps_data))
			{
				return "-";
			}
			else
			{
				return ps_data;
			}
		}
		
		#endregion
		
		#region 문자열에서 값 추출

		/// <summary>
		///  문자열에서 숫자만 추출하여 문자열로 리턴, 음수처리
		/// </summary>
		/// <param name="ps_data">문자열</param>
		/// <returns>string</returns>
		public static string ExtractNumberStr(string ps_data)
		{
			string ls_return = "";
			string ls_prefix = "";

			if (StringUtil.IsNullOrEmpty(ps_data) || ps_data.ToLower() == "null")
			{
				return "";
			}

			for (int i = 0; i < ps_data.Length; i++)
			{
				if (char.IsNumber(ps_data, i))
				{
					ls_return += ps_data[i].ToString();
				}
			}

			//음수처리			
			if (ps_data[0].ToString() == "-")
			{
				ls_prefix = "-";
			}

			return ls_prefix + ls_return;
		}

		/// <summary>
		///  문자열에서 숫자만 추출하여 숫자로 리턴, 문자만 입력되는 경우 0리턴, 음수처리 
		/// </summary>
		/// <param name="ps_data">문자열</param>
		/// <returns>string</returns>
		public static int ExtractNumberInt(string ps_data)
		{
			bool lb_rslt = false;
			string ls_prefix = "";
			string ls_return = "";

			if (StringUtil.IsNullOrEmpty(ps_data) || ps_data.ToLower() == "null")
			{
				return 0;
			}

			if (ps_data[0].ToString() == "-")
			{
				ls_prefix = "-";
			}

			for (int i = 0; i < ps_data.Length; i++)
			{
				if (char.IsNumber(ps_data, i))
				{
					ls_return += ps_data[i].ToString();
					lb_rslt = true;
				}
			}
			
			if (lb_rslt)
			{
				return Convert.ToInt32(ls_prefix + ls_return);
			}
			else
			{
				return 0;
			}
		}

		/// <summary>
		///  문자열에서 숫자만 추출하여 더블로 리턴, 문자만 입력되는 경우 0리턴, 음수처리, 소수점 처리 
		/// </summary>
		/// <param name="ps_data">문자열</param>
		/// <returns>string</returns>
		public static double ExtractNumberDbl(string ps_data)
		{
			bool lb_rslt = false;
			string ls_prefix = "";
			string ls_return = "";

			if (StringUtil.IsNullOrEmpty(ps_data) || ps_data.ToLower() == "null")
			{
				return 0;
			}

			if (ps_data[0].ToString() == "-")
			{
				ls_prefix = "-";
			}

			for (int i = 0; i < ps_data.Length; i++)
			{
				if (char.IsNumber(ps_data, i) || ps_data[i].ToString() == ".")
				{
					ls_return += ps_data[i].ToString();
					lb_rslt = true;
				}
			}

			if (lb_rslt)
			{
				return Convert.ToDouble(ls_prefix + ls_return);
			}
			else
			{
				return 0;
			}
		}

		/// <summary>
		/// 문자열에서 특정 문자열 사이의 값만 리턴
		/// </summary>
		/// <param name="ps_data">문자열</param>
		/// <param name="ps_st">비교시작문자</param>
		/// <param name="ps_ed">비교끝문자</param>
		/// <returns>string</returns>
		public static string ExtractStrBtwnChar(string ps_data, string ps_st, string ps_ed)
		{
			string ls_result;
			try
			{
				int li_st_tmp = ps_data.IndexOf(ps_st);
				int li_ed_tmp = ps_data.LastIndexOf(ps_ed);

				int li_st = li_st_tmp + ps_st.Length;
				int li_ed = (li_ed_tmp - li_st);

				ls_result = ps_data.Substring(li_st, li_ed);
			}
			catch
			{
				ls_result = ps_data;
			}

			return ls_result;
		}
		
		#endregion
		
		#region 문자열 치환

		/// <summary>
		///  \n을 <br />로 치환
		/// </summary>
		/// <param name="ps_data">문자열</param>
		/// <returns>string</returns>
		public static string ReplaceBR(string ps_data)
		{
			return ps_data.Replace("\n", "<br />");
		}
		
		#endregion
		
		#region 문자열 가공

		/// <summary>
		///  앞 문자열을 뒤 문자열과 비교해서 일치하면 리턴값으로 리턴, 아니면 앞 문자열로 리턴
		/// </summary>
		/// <param name="ps_compare_a">비교 앞 문자열</param>
		/// <param name="ps_compare_b">비교 뒤 문자열</param>
		/// <param name="ps_return">비교 뒤 문자열</param>
		/// <returns>string</returns>
		public static string CompareReplace(string ps_compare_a, string ps_compare_b, string ps_return)
		{
			string ls_return = "";
			if (ps_compare_a == ps_compare_b)
			{
				ls_return = ps_return;
			}
			else
			{
				if (!String.IsNullOrEmpty(ps_compare_a))
				{
					ls_return = ps_compare_a;
				}
				else
				{
					ls_return = "-";
				}
			}
			return ls_return;
		}

		/// <summary>
		/// 문자열이 특정길이보다 길면 특정길이만큼 자르고 뒤에 마스크를 붙여서 리턴
		/// </summary>
		/// <param name="ps_data">문자열</param>
		/// <param name="pi_index">인덱스</param>
		/// <returns></returns>
		public static string SubstrExt(string ps_data, int pi_index)
		{
			return SubstrExt(ps_data, pi_index, "...");
		}
		
		/// <summary>
		/// 문자열이 특정길이보다 길면 특정길이만큼 자르고 뒤에 마스크를 붙여서 리턴
		/// </summary>
		/// <param name="ps_data">문자열</param>
		/// <param name="pi_index">인덱스</param>
		/// <param name="ps_mask">마스크</param>
		/// <returns>string</returns>
		public static string SubstrExt(string ps_data, int pi_index, string ps_mask)
		{
			string ls_result = "";

			if (ps_data.Trim().Length > pi_index)
			{
				ls_result = ps_data.Substring(0, pi_index) + ps_mask;
			}
			else
			{
				ls_result = ps_data;
			}

			return ls_result;
		}

		/// <summary>
		/// 값이 있으면 입력한 문자로 감싸고, 없으면 빈 값으로 리턴
		/// 파일업로드, 파일다운로드에서 사용
		/// </summary>
		/// <param name="ps_data">데이터</param>
		/// <param name="ps_l">왼쪽</param>
		/// <param name="ps_r">오른쪽</param>
		/// <returns>string</returns>
		public static string DataWrapper(string ps_data, string ps_l, string ps_r)
		{
			string ls_result = "";

			if (!String.IsNullOrEmpty(ps_data))
			{
				ls_result = ps_l + ps_data + ps_r;
			}
			return ls_result;
		}


		/// <summary>
		/// 문자열에 세자리마다 콤마(,)를 넣어서 리턴. 소숫점 뒤는 리턴하지 않는다
		/// </summary>
		/// <param name="ps_data"></param>
		/// <returns></returns>
		public static string AddComma(string ps_data)
		{
			return AddComma(ps_data, true);
		}
		
		/// <summary>
		/// 문자열에 세자리마다 콤마(,)를 넣어서 리턴
		/// arg_lb_split_yn가 true이면 소숫점 뒤는 리턴하지 않는다
		/// </summary>
		/// <param name="ps_data">문자열</param>
		/// <param name="pb_split_yn">나눌지 여부(true이면 소숫점 뒤는 리턴하지 않는다)</param>
		/// <returns>string</returns>
		public static string AddComma(string ps_data, bool pb_split_yn)
		{
			string ls_result = "";
			string ls_sub1, ls_sub2;

			// 소수점을 기준으로 나눈다.
			if (ps_data.IndexOf(".") > 0)
			{
				ls_sub1 = ps_data.Substring(0, ps_data.IndexOf("."));
				ls_sub2 = ps_data.Substring(ps_data.IndexOf("."), ps_data.Length - ps_data.IndexOf("."));
			}
			else
			{
				ls_sub1 = ps_data;
				ls_sub2 = "";
			}

			ls_sub1 = String.Format("{0:#,##0}", Convert.ToInt32(ls_sub1));

			// 소숫점 뒤는 리턴하지 않는다.
			ls_result = pb_split_yn ? ls_sub1 : ls_sub1 + ls_sub2;

			// -,123,456,789는 -123,456,789로
			if (ls_result.LastIndexOf("-,") > 0)
			{
				ls_result = ls_result.Replace("-,", "-").Trim();
			}

			return ls_result;
		}

		/// <summary>
		/// 문자열에 콤마(,)를 제거하고 리턴
		/// </summary>
		/// <param name="ps_data">문자열</param>
		/// <returns>string</returns>
		public static string RemoveComma(string ps_data)
		{
			string ls_result = "";

			if (!String.IsNullOrEmpty(ps_data))
			{
				ls_result = ps_data.Replace(",", "");
			}
			else
			{
				ls_result = ps_data;
			}

			return ls_result;
		}

		/// <summary>
		/// 왼쪽을 지정된 문자로 채운다.
		/// </summary>
		/// <param name="ps_data">입력문자</param>
		/// <param name="pi_length">채울길이</param>
		/// <param name="ps_fill">채울문자열</param>
		/// <returns></returns>
		public static string LPad(string ps_data, int pi_length, string ps_fill)
		{
			string ls_result = "";
			int li_data_length = ps_data.Length;
			
			if (li_data_length > 0)
			{
				if (li_data_length < pi_length)
				{
					string ls_fill = String.Empty;
					for (int i = li_data_length; i < pi_length; i++)
					{
						ls_fill = ls_fill + ps_fill;
					}
					ls_result = ls_fill + ps_data;
				}
				else
				{
					return ps_data;
				}
			}

			return ls_result;
		}

		/// <summary>
		/// 오른쪽을 지정된 문자로 채운다.
		/// </summary>
		/// <param name="ps_data">입력문자</param>
		/// <param name="pi_length">채울길이</param>
		/// <param name="ps_fill">채울문자열</param>
		/// <returns></returns>
		public static string RPad(string ps_data, int pi_length, string ps_fill)
		{
			string ls_result = "";
			int li_data_length = ps_data.Length;

			if (li_data_length > 0)
			{
				if (li_data_length < pi_length)
				{
					string ls_fill = String.Empty;
					for (int i = li_data_length; i < pi_length; i++)
					{
						ls_fill = ls_fill + ps_fill;
					}
					ls_result = ps_data + ls_fill;
				}
				else
				{
					return ps_data;
				}
			}

			return ls_result;
		}

		/// <summary>
		/// 문자열 뒤에 탭문자를 붙여서 리턴
		/// </summary>
		/// <param name="ls_data"></param>
		/// <returns></returns>
		public static string AddTab(string ls_data)
		{
			string ls_result = "";
			if (ls_data.Length < 4)
			{
				ls_result = ls_data + "\t\t\t\t\t";
			}
			else if (4 <= ls_data.Length && ls_data.Length < 8)
			{
				ls_result = ls_data + "\t\t\t\t";
			}
			else if (8 <= ls_data.Length && ls_data.Length < 16)
			{
				ls_result = ls_data + "\t\t\t";
			}
			else if (16 <= ls_data.Length && ls_data.Length < 24)
			{
				ls_result = ls_data + "\t\t";
			}
			else if (24 <= ls_data.Length)
			{
				ls_result = ls_data + "\t";
			}

			return ls_result;
		}

		#endregion

        #region 로그 관련

        /// <summary>
        /// 데이터팩에서 데이터 추출
        /// </summary>
        /// <param name="ps_source"></param>
        /// <param name="po_dp"></param>
        /// <returns></returns>
        public static string ExtractDataInfo(string ps_source, DataPack po_dp)
        {
            string ls_return = ps_source + "<br><br>";

            for (int i = 0; i < po_dp.Properties.Count; i++)
            {
                ls_return += "@" + po_dp.Properties[i].Name + "=" + po_dp[po_dp.Properties[i].Name].ToString() + "<br>";
            }

            return ls_return;
        }

		/// <summary>
		/// 데이터팩에서 데이터 추출(SP 실행가능 파라미터 형식)
		/// </summary>
		/// <param name="ps_sp"></param>
		/// <param name="po_dp"></param>
		/// <returns></returns>
		public static string ExtractDataParam(string ps_sp, DataPack po_dp)
		{
			string ls_return = "exec " + ps_sp + "<br><br>";

			for (int i = 0; i < po_dp.Properties.Count; i++)
			{
				string ls_var = "@" + po_dp.Properties[i].Name;
				string ls_value = po_dp[po_dp.Properties[i].Name].ToString();

				ls_return += ls_var + "='" + ls_value + "',<br>";
			}

			return ls_return.Substring(0, ls_return.Length - 5) + ";";
		}

		/// <summary>
		/// 데이터테이블에서 데이터 추출
		/// </summary>
		/// <param name="ps_source"></param>
		/// <param name="po_dt"></param>
		/// <returns></returns>
		public static string ExtractDataInfo(string ps_source, DataTable po_dt)
		{
			string ls_return = ps_source + "<br><br>";

			if (po_dt.Rows.Count > 0)
			{
				for (int i = 0; i < po_dt.Rows.Count; i++)
				{
					ls_return += "<br>Row Number : " + i + "<br>";

					for (int j = 0; j < po_dt.Columns.Count; j++)
					{
						String ls_field_name = po_dt.Columns[j].ColumnName;
						ls_return += AddTab(ls_field_name) + po_dt.Rows[i][j].ToString() + "<br>";
					}
				}
			}

			return ls_return;
		}

		/// <summary>
		/// 데이터셋에서 데이터 추출
		/// </summary>
		/// <param name="ps_source"></param>
		/// <param name="po_ds"></param>
		/// <param name="ps_table_name"></param>
		/// <returns></returns>
		public static string ExtractDataInfo(string ps_source, DataSet po_ds, String ps_table_name)
        {
            string ls_return = ps_source + "<br><br>";

			if (DataSetUtil.CheckRowCount(po_ds, ps_table_name))
			{
				for (int i = 0; i < DataSetUtil.GetRowCount(po_ds, ps_table_name); i++)
				{
					ls_return += "<br>Row Number : " + i + "<br>";
					//데이터셋내 테이블의 필드명을 가져온다.
					for (int j = 0; j < po_ds.Tables[ps_table_name].Columns.Count; j++ )
					{
						String ls_field_name = po_ds.Tables[ps_table_name].Columns[j].ColumnName;
						ls_return += AddTab(ls_field_name) + DataSetUtil.GetFldStr(po_ds, ps_table_name, i, ls_field_name) + "<br>";
					}
				}
			}

            return ls_return;
        }

        /// <summary>
        /// SqlCommand에서 파라미터값 추출
        /// </summary>
        /// <param name="po_cmd">SqlCommand 정보</param>
        public static string ExtractDataInfo(SqlCommand po_cmd)
        {
            string ls_return = po_cmd.CommandText + "<br><br>";

            for (int i = 0; i < po_cmd.Parameters.Count; i++)
            {
                ls_return += po_cmd.Parameters[i].ToString() + "=" + po_cmd.Parameters[po_cmd.Parameters[i].ToString()].Value + "<br>";
            }

            return ls_return;
        }

        /// <summary>
        /// 예외정보를 HTML문으로 생성하여 리턴
        /// </summary>
        /// <param name="e">예외정보</param>
		/// <param name="ps_query">쿼리정보</param>
        public static string GenerateHtmlErr(Exception e, string ps_query)
        {
            string ls_return = "";

            ls_return = "<table cellpadding=4 cellspacing=0 border=0 width=100%><tr><td width=16% class=td_tl>";
            ls_return += "Error Souce</td><td width=84% class=td_tlr>" + e.Source + "</td></tr><tr><td class=td_tl>"
                + "Error Message</td><td class=td_tlr><font color='red'>" + e.Message + "</font></td></tr><tr><td class=td_tl>"
                + "Stack</td><td class=td_tlr>" + e.StackTrace + "</td></tr><tr><td class=td_tbl>"
                + "Query</td><td class=td_tblr><font color='blue'>" + ps_query + "</font></td></tr></table>";

            ls_return = ls_return.Replace("\r\n", "<br>");

            return ls_return;
        }

        #endregion

		#region 문자열 검증

		/// <summary>
		/// 문자열이 Base64형식인지 여부 리턴
		/// </summary>
		/// <param name="ps_source"></param>
		/// <returns></returns>
		public static bool IsBase64(string ps_source)
		{
			try
			{
				System.Convert.FromBase64String(ps_source);
				return true;
			}
			catch(FormatException ex)
			{
				return false;
			}
		}

		#endregion
	}
}
